/*
 * Copyright 2013 Pavel Stastny <pavel.stastny at gmail.com>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.aplikator.server.processes.impl.processes;

import java.io.File;
import static org.aplikator.server.processes.OSProcessConfiguration.*;

import org.apache.commons.lang.SystemUtils;
import org.aplikator.server.processes.OSProcessConfiguration;
import org.aplikator.server.processes.Process;
import org.aplikator.server.processes.ProcessFactory;
import org.aplikator.server.processes.ProcessManager;
import org.aplikator.server.processes.RunnableSerializationAware;
import org.aplikator.server.processes.Work;
import org.aplikator.server.processes.impl.processes.unix.UnixOSProcess;
import org.aplikator.server.processes.impl.processes.windows.WindowsOSProcess;

/**
 *
 * @author Pavel Stastny <pavel.stastny at gmail.com>
 */
public class OSProcessFactory extends ProcessFactory <OSProcessConfiguration>{

    private String appname;

    public OSProcessFactory(String appname) {
        this.appname = appname;
    }
    
    @Override
    public Process create(RunnableSerializationAware runnable) {
        if (SystemUtils.IS_OS_LINUX     || SystemUtils.IS_OS_UNIX) {
            UnixOSProcess upr = new UnixOSProcess(generateProcessId(), this.appname,runnable, new String[]{}, new String[] {});
            ProcessManager.getManager().registerProcess(upr);
            return upr;
        } else if (SystemUtils.IS_OS_WINDOWS) {
            WindowsOSProcess wpr = new WindowsOSProcess(generateProcessId(), this.appname,runnable, new String[]{}, new String[] {});
            ProcessManager.getManager().registerProcess(wpr);
            return wpr;
        } else throw new UnsupportedOperationException("unsupported OS");
    }

    public void redirectStreams(OSProcessConfiguration conf, AbstractOSProcess process) {
        if (conf.getConfigurationItem(OSProcessConfiguration.STERR_OUT_FILE)!=null) {
            String sterr = (String) conf.getConfigurationItem(STERR_OUT_FILE);
            process.redirectErrorStream(new File(sterr));
        }
        if (conf.getConfigurationItem(OSProcessConfiguration.STD_OUT_FILE)!=null) {
            String stout = (String) conf.getConfigurationItem(STD_OUT_FILE);
            process.redirectOutputStream(new File(stout));
        }
    }
    
    @Override
    public Process create(OSProcessConfiguration conf, RunnableSerializationAware runnable) {
        if (SystemUtils.IS_OS_LINUX     || SystemUtils.IS_OS_UNIX) {
            String[] classpathlib = (String[])conf.getConfigurationItem(CLASSPATH_LIB);
            String[] classpath =  (String[])conf.getConfigurationItem(CLASSPATH);
            UnixOSProcess process = new UnixOSProcess(generateProcessId(), this.appname,runnable,classpathlib,classpath);
            redirectStreams(conf, process);
            ProcessManager.getManager().registerProcess(process);
            return process;
        } else if (SystemUtils.IS_OS_WINDOWS) {
            String[] classpathlib = (String[])conf.getConfigurationItem(CLASSPATH_LIB);
            String[] classpath =  (String[])conf.getConfigurationItem(CLASSPATH);
            WindowsOSProcess wpr = new WindowsOSProcess(generateProcessId(), this.appname,runnable,classpathlib,classpath);
            redirectStreams(conf, wpr);
            ProcessManager.getManager().registerProcess(wpr);
            return wpr;
        } else throw new UnsupportedOperationException("unsupported OS");
    }

    @Override
    public Process create(Work... works) {
        if (SystemUtils.IS_OS_LINUX     || SystemUtils.IS_OS_UNIX) {
            UnixOSProcess upr = new UnixOSProcess(generateProcessId(), this.appname,works, new String[]{}, new String[] {});
            ProcessManager.getManager().registerProcess(upr);
            return upr;
        } else if (SystemUtils.IS_OS_WINDOWS) {
            WindowsOSProcess upr = new WindowsOSProcess(generateProcessId(), this.appname,works, new String[]{}, new String[] {});
            ProcessManager.getManager().registerProcess(upr);
            return upr;
        } else throw new UnsupportedOperationException("unsupported OS");
    }

    @Override
    public Process create(OSProcessConfiguration conf, String[] params, Work... works) {
        if (SystemUtils.IS_OS_LINUX     || SystemUtils.IS_OS_UNIX) {
            UnixOSProcess upr =  new UnixOSProcess(generateProcessId(), this.appname,works, new String[]{}, new String[] {});
            redirectStreams(conf, upr);
            ProcessManager.getManager().registerProcess(upr);
            return upr;
        } else if (SystemUtils.IS_OS_WINDOWS) {
            WindowsOSProcess wpr =  new WindowsOSProcess(generateProcessId(), this.appname,works, new String[]{}, new String[] {});
            redirectStreams(conf, wpr);
            ProcessManager.getManager().registerProcess(wpr);
            return wpr;
        } else throw new UnsupportedOperationException("unsupported OS");
    }

}
